/*
 *             Copyright (C) 2024 Steve Jrong
 *
 * 	   GitHub Homepage: https://www.github.com/SteveJrong
 *      Gitee Homepage: https://gitee.com/stevejrong1024
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.stevejrong.waiter.user.domainservice.factory;

import com.stevejrong.waiter.common.component.util.DateTimeUtil;
import com.stevejrong.waiter.common.component.util.EnumUtil;
import com.stevejrong.waiter.user.dbsdk.model.GuestPO;
import com.stevejrong.waiter.user.model.aggregates.Guest;
import com.stevejrong.waiter.user.model.valueobjects.*;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Optional;

/**
 * 聚合工厂类 - 顾客聚合工厂类
 *
 * @author Steve Jrong
 * @since 1.0
 */
public final class GuestFactory {

    /**
     * 将基础设施层中的数据持久化对象（PO），转换为领域层的领域对象（DO）
     * <p>
     * 用于从数据库加载数据到领域中
     *
     * @param guestPO 顾客数据持久化对象（PO）
     * @return 顾客领域对象（DO）
     */
    public static Guest getDomainObjectFromPO(GuestPO guestPO) {
        Guest guest = new Guest();

        guest.setMainId(guestPO.getMainId());
        guest.setCreateAt(guestPO.getCreateAt());
        guest.setUpdateAt(guestPO.getUpdateAt());

        PartnerWxInfo wxInfo = new PartnerWxInfo();
        wxInfo.setUserOpenId(guestPO.getPartnerWxUserOpenId());
        wxInfo.setUserUnionId(guestPO.getPartnerWxUserUnionId());
        wxInfo.setUserNickName(guestPO.getPartnerWxUserNickName());
        wxInfo.setUserAvatarUrl(guestPO.getPartnerWxUserAvatarUrl());
        wxInfo.setUserGender(EnumUtil.getEnumByCode(Gender.class, guestPO.getPartnerWxUserGender()));
        wxInfo.setUserCountry(guestPO.getPartnerWxUserCountry());
        wxInfo.setUserProvince(guestPO.getPartnerWxUserProvince());
        wxInfo.setUserCity(guestPO.getPartnerWxUserCity());
        wxInfo.setHasAdvancedAuth(EnumUtil.getEnumByCode(HasAdvanceAuth.class, guestPO.getPartnerWxHasAdvancedAuth()));
        guest.setPartnerWxInfo(wxInfo);

        PartnerAliPayInfo aliPayInfo = new PartnerAliPayInfo();
        aliPayInfo.setUserId(guestPO.getPartnerAlipayUserId());
        aliPayInfo.setUserNickName(guestPO.getPartnerAlipayUserNickName());
        aliPayInfo.setUserAvatarUrl(guestPO.getPartnerAlipayUserAvatarUrl());
        guest.setPartnerAliPayInfo(aliPayInfo);

        guest.setTel(guestPO.getTel());
        guest.setStatus(EnumUtil.getEnumByCode(Status.class, guestPO.getStatus()));
        guest.setHasDeleted(EnumUtil.getEnumByCode(HasDeleted.class, guestPO.getHasDeleted()));

        return guest;
    }

    /**
     * 根据领域层的领域对象DO，创建基础设施层中的数据持久化对象（PO）
     * <p>
     * 用于将领域对象持久化到数据库中
     *
     * @param guest 顾客领域对象（DO）
     * @return 顾客数据持久化对象（PO）
     */
    public static GuestPO createPersistentObjectFromDO(Guest guest) {
        GuestPO guestPO = new GuestPO();

        guestPO.setMainId(guest.getMainId());
        PartnerWxInfo partnerWxInfo = Optional.ofNullable(guest.getPartnerWxInfo())
                .orElse(new PartnerWxInfo());
        guestPO.setPartnerWxUserOpenId(StringUtils.isBlank(partnerWxInfo.getUserOpenId()) ? StringUtils.EMPTY : partnerWxInfo.getUserOpenId());
        guestPO.setPartnerWxUserUnionId(StringUtils.isBlank(partnerWxInfo.getUserUnionId()) ? StringUtils.EMPTY : partnerWxInfo.getUserUnionId());
        guestPO.setPartnerWxUserNickName(StringUtils.isBlank(partnerWxInfo.getUserNickName()) ? StringUtils.EMPTY : partnerWxInfo.getUserNickName());
        guestPO.setPartnerWxUserAvatarUrl(StringUtils.isBlank(partnerWxInfo.getUserAvatarUrl()) ? StringUtils.EMPTY : partnerWxInfo.getUserAvatarUrl());
        guestPO.setPartnerWxUserGender(ObjectUtils.isEmpty(partnerWxInfo.getUserGender()) ? Gender.UNKNOWN.code() : partnerWxInfo.getUserGender().code());
        guestPO.setPartnerWxUserCountry(StringUtils.isBlank(partnerWxInfo.getUserCountry()) ? StringUtils.EMPTY : partnerWxInfo.getUserCountry());
        guestPO.setPartnerWxUserProvince(StringUtils.isBlank(partnerWxInfo.getUserProvince()) ? StringUtils.EMPTY : partnerWxInfo.getUserProvince());
        guestPO.setPartnerWxUserCity(StringUtils.isBlank(partnerWxInfo.getUserCity()) ? StringUtils.EMPTY : partnerWxInfo.getUserCity());
        guestPO.setPartnerWxHasAdvancedAuth(ObjectUtils.isEmpty(partnerWxInfo.getHasAdvancedAuth()) ? HasAdvanceAuth.NO_ADVANCE_AUTH.code() : partnerWxInfo.getHasAdvancedAuth().code());

        PartnerAliPayInfo partnerAliPayInfo = Optional.ofNullable(guest.getPartnerAliPayInfo())
                .orElse(new PartnerAliPayInfo());
        guestPO.setPartnerAlipayUserId(StringUtils.isBlank(partnerAliPayInfo.getUserId()) ? StringUtils.EMPTY : partnerAliPayInfo.getUserId());
        guestPO.setPartnerAlipayUserNickName(StringUtils.isBlank(partnerAliPayInfo.getUserNickName()) ? StringUtils.EMPTY : partnerAliPayInfo.getUserNickName());
        guestPO.setPartnerAlipayUserAvatarUrl(StringUtils.isBlank(partnerAliPayInfo.getUserAvatarUrl()) ? StringUtils.EMPTY : partnerAliPayInfo.getUserAvatarUrl());

        guestPO.setTel(StringUtils.isBlank(guest.getTel()) ? StringUtils.EMPTY : guest.getTel());
        guestPO.setStatus(ObjectUtils.isEmpty(guest.getStatus()) ? Status.ENABLE.code() : guest.getStatus().code());
        guestPO.setHasDeleted(ObjectUtils.isEmpty(guest.getHasDeleted()) ? HasDeleted.NO_DELETED.code() : guest.getHasDeleted().code());
        guestPO.setCreateAt(ObjectUtils.isEmpty(guest.getCreateAt()) ? DateTimeUtil.getLocalDateTimeByNow() : guest.getCreateAt());
        guestPO.setUpdateAt(ObjectUtils.isEmpty(guest.getUpdateAt()) ? null : guest.getUpdateAt());

        return guestPO;
    }
}